﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using AutoMapper;
using Mehdime.Entity;
using WikeSoft.Core.Exception;
using WikeSoft.Core.Extension;
using WikeSoft.Data;
using WikeSoft.Enterprise.Entities;
using WikeSoft.Enterprise.Interfaces.Sys;
using WikeSoft.Enterprise.Interfaces.WorkFlow;
using WikeSoft.WorkFlowEngine.Interfaces;
using WikeSoft.WorkFlowEngine.Models;

namespace WikeSoft.Enterprise.AppServices.WorkFlow
{
    public class WorkFlowService : IWorkFlowService
    {
        private readonly IMapper _mapper;
        private readonly IDbContextScopeFactory _dbContextScopeFactory;
        private readonly IWorkFlowInstanceService _flowInstanceService;
        private readonly IDepartmentService _departmentService;
        private readonly IKeyValueService _keyValueService;
        public WorkFlowService(IMapper mapper, IDbContextScopeFactory dbContextScopeFactory, IWorkFlowInstanceService flowInstanceService, IDepartmentService departmentService, IKeyValueService keyValueService)
        {
            _mapper = mapper;
            _dbContextScopeFactory = dbContextScopeFactory;
            _flowInstanceService = flowInstanceService;
            _departmentService = departmentService;
            _keyValueService = keyValueService;
        }

        public string GetAuthorityUser(WorkFlowAuthority authority, string userId)
        {
            using (var scope = _dbContextScopeFactory.CreateReadOnly())
            {
                var db = scope.DbContexts.Get<WikeDbContext>();
                string authorityUser = string.Empty;
                if (authority.UserIds.IsNotBlank())
                {
                    authorityUser += authority.UserIds;
                }
                if (authority.RoleIds.IsNotBlank())
                {
                    string[] roleIds = authority.RoleIds.Split(';');
                    var roleGuids = roleIds.Where(c => c.Length > 0).Select(x =>x).ToArray();

                    var roleUsers = db.SysUsers.Where(c => c.DepartmentId != null && c.SysRoles.Any(x => x.IsDelete == false && roleGuids.Contains(x.Id)));

                    var roleUserDepartmentIds = roleUsers.Select(c => c.DepartmentId).Distinct().ToList();

                    var departments = _departmentService.GetParentDepartmentByUserId(userId);
                    //B.All(b => A.Contains(b))
                    //if (departments.Contains())



                    var departmentIds = departments.Select(c => c.Id).ToList();

                    //判断是否有层级关系
                    //var include = departmentIds.All(x => roleUserDepartmentIds.Contains(x));
                    //如果authorityUser的RoleIds中的用户所在部门，和当前用户的父级部门存在关联，则说明是得到父级部门的角色
                    var include = departmentIds.Any(x => roleUserDepartmentIds.Contains(x));
                    List<SysUser> users;
                    if (include)
                    {
                        users = db.SysUsers.Where(c => c.IsDelete == false && departmentIds.Contains(c.DepartmentId) && c.SysRoles.Any(x => roleGuids.Contains(x.Id))).ToList();
                    }
                    else
                    {
                        users = db.SysUsers.Where(c => c.IsDelete == false && c.SysRoles.Any(x => roleGuids.Contains(x.Id))).ToList();
                    }
                    //TODO：如果找不到责任用户，说明处理的角色不用跟部门进行级联。
                    authorityUser += users.Select(c => c.Id).ToList().Join(";");
                }
                return authorityUser;
            }
        }

        public string GetAuthorityUsers(List<WorkFlowAuthority> authorities, string userId)
        {

            StringBuilder ret = new StringBuilder(userId.ToString().ToUpper()+";");
            foreach (var authority in authorities)
            {
                string str = this.GetAuthorityUser(authority, userId)+";";
                ret.Append(str);
            }
            return ret.ToString().ToUpper().Replace(";;",";");

        }

        
      
    }
}
